package com.econ.powercloud.ems.common.util;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class JacksonExtUtil {

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
    private static final JavaTimeModule JTM = new JavaTimeModule();

    static {
        OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
        // 为null的数据不序列化
        OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);

        JTM.addDeserializer(LocalDateTime.class, new JsonDeserializer<LocalDateTime>(){
            @Override
            public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
                Long timestamp = p.getLongValue();
                return LocalDateTime.ofEpochSecond(timestamp / 1000, 0, ZoneOffset.ofHours(8));
            }
        });
        JTM.addSerializer(LocalDateTime.class, new JsonSerializer<LocalDateTime>(){
            @Override
            public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                gen.writeNumber(value.toInstant(ZoneOffset.ofHours(8)).toEpochMilli());
            }
        });
        OBJECT_MAPPER.registerModule(JTM);
    }

    public static void jsonLeaf(JsonNode node, Map<String, String> result, String previousKey) {
        if (node.isValueNode()) {
            result.put(previousKey, node.asText());
            return;
        }
        if (node.isObject()) {
            Iterator<Map.Entry<String, JsonNode>> it = node.fields();
            while (it.hasNext()) {
                Map.Entry<String, JsonNode> entry = it.next();
                String key = entry.getKey();
                String absoluteKey = StringUtils.isBlank(previousKey) ? key : previousKey + "." + key;
                jsonLeaf(entry.getValue(), result, absoluteKey);
            }
        }
        if (node.isArray()) {
            int i = 0;
            Iterator<JsonNode> it = node.iterator();
            while (it.hasNext()) {
                String thisKey = StringUtils.isBlank(previousKey) ? null : previousKey + "[" + i+"]";
                jsonLeaf(it.next(), result, thisKey);
                i ++;
            }
        }
    }

    public static Map<String, String> flatJsonToMap(String json){
        Map<String, String> result = new HashMap<>();
        try {
            JsonNode node = OBJECT_MAPPER.readTree(json);
            jsonLeaf(node, result, null);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        return result;
    }

    public static void main(String[] args) {
        String txt = "{\"status\":\"success\",\"data\":{\"resultType\":\"vector\",\"result\":[{\"metric\":{\"instance\":\"192.168.86.150:9100\"},\"value\":[1669169468.982,\"1.1769841269808068\"]}]}}";
        Map<String, String> map = flatJsonToMap(txt);
        Iterator iterator =map.entrySet().iterator();
        while(iterator.hasNext()){
            Map.Entry entry = (Map.Entry) iterator.next();
            System.out.println(entry.getKey() + " == " + entry.getValue());
        }
    }
}
